home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <math.h>
- #ifndef NOUNISTD_H
- #include <unistd.h>
- #endif
- #include "dalloca.h"
- #include "head.h"
-
- #define ERRR (-1)
-
- static int mrqcof(double **coef, double *f, double *y, double *sig, int ndata, double *a, int ma, int *lista, int mfit, double **alpha, double *beta, double *chisq);
- static int gaussj(double **a, int n, double **b, int m);
- static int covsrt(double **covar, int ma, int *lista, int mfit);
-
-
- int Ft_mrqmin(double **coef, double *f, double *y, double *sig, int ndata, double *a, int ma, int *lista, int mfit, double **covar, double **alpha, double *chisq, double *alamda)
- {
- int k,kk,j,ihit;
- static double *da = 0;
- static double *aold = 0;
- static double **oneda = 0;
- static double *beta = 0;
- static int sma = 0;
- static int smfit = 0;
- static double ochisq;
- double *Ft_dvector(int nl, int nh);
- double **Ft_dmatrix(int nrl, int nrh, int ncl, int nch);
- void Ft_free_dmatrix(double **m, int nrl, int nrh, int ncl, int nch);
- void Ft_free_dvector(double *v, int nl, int nh);
-
- if (*alamda < 0.0) { /* clean and allocate on start */
- if (oneda)
- Ft_free_dmatrix(oneda, 1, smfit, 1, 1); oneda = 0;
- if (aold)
- Ft_free_dvector(aold, 1, sma); aold = 0;
- if (da)
- Ft_free_dvector(da, 1, sma); da = 0;
- if (beta)
- Ft_free_dvector(beta, 1, sma); beta = 0;
- sma = ma;
- smfit = mfit;
- if ((oneda=Ft_dmatrix(1,mfit,1,1)) == NULL) {
- fprintf(stderr, "mrqmin: Allocation error.\n");
- Ft_catcher(ERRR);
- }
- if ((aold=Ft_dvector(1,ma)) == NULL) {
- fprintf(stderr, "mrqmin: Allocation error.\n");
- Ft_free_dmatrix(oneda, 1, mfit, 1, 1); oneda = 0;
- Ft_catcher(ERRR);
- }
- if ((da=Ft_dvector(1,ma)) == NULL) {
- Ft_free_dmatrix(oneda, 1, mfit, 1, 1); oneda = 0;
- Ft_free_dvector(aold, 1, ma); aold = 0;
- fprintf(stderr, "mrqmin: Allocation error.\n");
- Ft_catcher(ERRR);
- }
- if ((beta=Ft_dvector(1,ma)) == NULL) {
- Ft_free_dmatrix(oneda, 1, mfit, 1, 1); oneda = 0;
- Ft_free_dvector(aold, 1, ma); aold = 0;
- Ft_free_dvector(da, 1, ma); da = 0;
- fprintf(stderr, "mrqmin: Allocation error.\n");
- Ft_catcher(ERRR);
- }
- kk=mfit+1;
- for (j=1;j<=ma;j++) {
- ihit=0;
- for (k=1;k<=mfit;k++)
- if (lista[k] == j) ihit++;
- if (ihit == 0)
- lista[kk++]=j;
- else if (ihit > 1) {
- fprintf(stderr, "mrqmin-1: Bad Lista permutation.\n");
- Ft_free_dmatrix(oneda, 1, mfit, 1, 1); oneda = 0;
- Ft_free_dvector(aold, 1, ma); aold = 0;
- Ft_free_dvector(da, 1, ma); da = 0;
- Ft_free_dvector(beta, 1, ma); beta = 0;
- Ft_catcher(ERRR);
- }
- }
- if (kk != ma+1) {
- fprintf(stderr, "mrqmin-2: Bad Lista permutation.\n");
- Ft_free_dmatrix(oneda, 1, mfit, 1, 1); oneda = 0;
- Ft_free_dvector(aold, 1, ma); aold = 0;
- Ft_free_dvector(da, 1, ma); da = 0;
- Ft_free_dvector(beta, 1, ma); beta = 0;
- Ft_catcher(ERRR);
- }
- *alamda=0.001;
- if (mrqcof(coef,f,y,sig,ndata,a,ma,lista,mfit,alpha,beta,chisq)
- == ERRR) { /* first shut */
- Ft_free_dmatrix(oneda, 1, mfit, 1, 1); oneda = 0;
- Ft_free_dvector(aold, 1, ma); aold = 0;
- Ft_free_dvector(da, 1, ma); da = 0;
- Ft_free_dvector(beta, 1, ma); beta = 0;
- Ft_catcher(ERRR);
- }
- ochisq=(*chisq);
- }
- for (j=1;j<=mfit;j++) {
- for (k=1;k<=mfit;k++) covar[j][k]=alpha[j][k];
- covar[j][j]=alpha[j][j]*(1.0+(*alamda));
- oneda[j][1]=beta[j];
- }
- if (gaussj(covar,mfit,oneda,1) == ERRR) {
- Ft_free_dmatrix(oneda, 1, mfit, 1, 1); oneda = 0;
- Ft_free_dvector(aold, 1, ma); aold = 0;
- Ft_free_dvector(da, 1, ma); da = 0;
- Ft_free_dvector(beta, 1, ma); beta = 0;
- Ft_catcher(ERRR);
- }
- for (j=1;j<=mfit;j++)
- da[j]=oneda[j][1];
- if (*alamda == 0.0) { /* get error and clean up */
- covsrt(covar,ma,lista,mfit);
- Ft_free_dmatrix(oneda, 1, mfit, 1, 1); oneda = 0;
- Ft_free_dvector(aold, 1, ma); aold = 0;
- Ft_free_dvector(da, 1, ma); da = 0;
- Ft_free_dvector(beta, 1, ma); beta = 0;
- return(0);
- }
- for (j=1;j<=ma;j++) aold[j]=a[j];
- for (j=1;j<=mfit;j++)
- a[lista[j]] += da[j];
- if (mrqcof(coef,f,y,sig,ndata,a,ma,lista,mfit,covar,da,chisq)
- == ERRR) {
- Ft_free_dmatrix(oneda, 1, mfit, 1, 1); oneda = 0;
- Ft_free_dvector(aold, 1, ma); aold = 0;
- Ft_free_dvector(da, 1, ma); da = 0;
- Ft_free_dvector(beta, 1, ma); beta = 0;
- Ft_catcher(ERRR);
- }
- if (*chisq < ochisq) {
- *alamda *= 0.1;
- ochisq=(*chisq);
- for (j=1;j<=mfit;j++) {
- for (k=1;k<=mfit;k++) alpha[j][k]=covar[j][k];
- beta[j]=da[j];
- }
- } else {
- for (j=1;j<=ma;j++) a[j]=aold[j];
- *alamda *= 10.0;
- *chisq=ochisq;
- }
- return(0);
- }
-
- static int mrqcof(double **coef, double *f, double *y, double *sig, int ndata, double *a, int ma, int *lista, int mfit, double **alpha, double *beta, double *chisq)
- {
- int i, j, k;
- double wt, sig2i, dy;
- void Ft_fml_fit(int ndata);
-
- for (j=1;j<=mfit;j++) {
- for (k=1;k<=j;k++)
- alpha[j][k]=0.0;
- beta[j]=0.0;
- }
- *chisq=0.0;
- Ft_fml_fit(ndata);
- for (i=1;i<=ndata;i++) {
- sig2i=1.0/(sig[i]*sig[i]);
- dy=y[i]-f[i];
- for (j=1;j<=mfit;j++) {
- wt=coef[lista[j]][i]*sig2i;
- for (k=1;k<=j;k++)
- alpha[j][k] += wt*coef[lista[k]][i];
- beta[j] += dy*wt;
- }
- (*chisq) += dy*dy*sig2i;
- }
- for (j=2;j<=mfit;j++)
- for (k=1;k<=j-1;k++)
- alpha[k][j]=alpha[j][k];
- return(0);
- }
-
- static int covsrt(double **covar, int ma, int *lista, int mfit)
- {
- int i,j;
- double swap;
-
- for (j=1;j<ma;j++)
- for (i=j+1;i<=ma;i++) covar[i][j]=0.0;
- for (i=1;i<mfit;i++)
- for (j=i+1;j<=mfit;j++) {
- if (lista[j] > lista[i])
- covar[lista[j]][lista[i]]=covar[i][j];
- else
- covar[lista[i]][lista[j]]=covar[i][j];
- }
- swap=covar[1][1];
- for (j=1;j<=ma;j++) {
- covar[1][j]=covar[j][j];
- covar[j][j]=0.0;
- }
- covar[lista[1]][lista[1]]=swap;
- for (j=2;j<=mfit;j++) covar[lista[j]][lista[j]]=covar[1][j];
- for (j=2;j<=ma;j++)
- for (i=1;i<=j-1;i++) covar[i][j]=covar[j][i];
-
- return(0);
- }
-
- #define SWAP(a,b) {double temp=(a);(a)=(b);(b)=temp;}
-
- static int gaussj(double **a, int n, double **b, int m)
- {
- int *indxc,*indxr,*ipiv;
- int i,icol,irow,j,k,l,ll;
- double big,dum,pivinv;
-
- AIVECTOR(indxc, 1, n, "gaussj", return);
- AIVECTOR(indxr, 1, n, "gaussj", return);
- AIVECTOR(ipiv, 1, n, "gaussj", return);
-
- icol = irow = 1;
- for (j=1;j<=n;j++)
- ipiv[j]=0;
- for (i=1;i<=n;i++) {
- big=0.0;
- for (j=1;j<=n;j++)
- if (ipiv[j] != 1)
- for (k=1;k<=n;k++) {
- if (ipiv[k] == 0) {
- if (fabs(a[j][k]) >= big) {
- big=fabs(a[j][k]);
- irow=j;
- icol=k;
- }
- } else if (ipiv[k] > 1) {
- fprintf(stderr, "gaussj: Singular Matrix 1.\n");
- return(ERRR);
- }
- }
- ++(ipiv[icol]);
- if (irow != icol) {
- for (l=1;l<=n;l++) SWAP(a[irow][l],a[icol][l])
- for (l=1;l<=m;l++) SWAP(b[irow][l],b[icol][l])
- }
- indxr[i]=irow;
- indxc[i]=icol;
- if (a[icol][icol] == 0.0) {
- fprintf(stderr, "gaussj: Singular Matrix 2.\n");
- return(ERRR);
- }
- pivinv=1.0/a[icol][icol];
- a[icol][icol]=1.0;
- for (l=1;l<=n;l++) a[icol][l] *= pivinv;
- for (l=1;l<=m;l++) b[icol][l] *= pivinv;
- for (ll=1;ll<=n;ll++)
- if (ll != icol) {
- dum=a[ll][icol];
- a[ll][icol]=0.0;
- for (l=1;l<=n;l++) a[ll][l] -= a[icol][l]*dum;
- for (l=1;l<=m;l++) b[ll][l] -= b[icol][l]*dum;
- }
- }
- for (l=n;l>=1;l--) {
- if (indxr[l] != indxc[l])
- for (k=1;k<=n;k++)
- SWAP(a[k][indxr[l]],a[k][indxc[l]]);
- }
- return(0);
- }
-
- #undef SWAP
-
- int Ft_lfit(double **coef, double *y, double *sig, int ndata, double *a, int ma, int *lista, int mfit, double **covar, double *chisq)
- {
- int k,kk,j,ihit,i;
- double ym,wt,sum,sig2i,**beta;
- double tmp;
-
- ADMATRIX(beta, 1, ma, 1, 1, "lfit", Ft_catcher);
- kk=mfit+1;
- for (j=1;j<=ma;j++) {
- ihit=0;
- for (k=1;k<=mfit;k++)
- if (lista[k] == j) ihit++;
- if (ihit == 0)
- lista[kk++]=j;
- else if (ihit > 1) {
- fprintf(stderr, "lfit: Bad 'adjust' permutation-1.");
- Ft_catcher(ERRR);
- }
- }
- if (kk != (ma+1)) {
- fprintf(stderr, "lfit: Bad 'adjust' permutation-2.");
- Ft_catcher(ERRR);
- }
- for (j=1;j<=mfit;j++) {
- for (k=1;k<=mfit;k++) covar[j][k]=0.0;
- beta[j][1]=0.0;
- }
- for (i=1;i<=ndata;i++) {
- ym=y[i];
- if (mfit < ma)
- for (j=(mfit+1);j<=ma;j++)
- ym -= a[lista[j]]*coef[lista[j]][i];
- sig2i=1.0/(sig[i]*sig[i]);
- for (j=1;j<=mfit;j++) {
- wt=coef[lista[j]][i]*sig2i;
- for (k=1;k<=j;k++)
- covar[j][k] += wt*coef[lista[k]][i];
- beta[j][1] += ym*wt;
- }
- }
- if (mfit > 1)
- for (j=2;j<=mfit;j++)
- for (k=1;k<=j-1;k++)
- covar[k][j]=covar[j][k];
- if (gaussj(covar,mfit,beta,1) == ERRR) {
- Ft_catcher(ERRR);
- }
- for (j=1;j<=mfit;j++) a[lista[j]]=beta[j][1];
- *chisq=0.0;
- for (i=1;i<=ndata;i++) {
- for (sum=0.0,j=1;j<=ma;j++) sum += a[j]*coef[j][i];
- tmp = (y[i]-sum)/sig[i];
- *chisq += tmp*tmp;
- }
- covsrt(covar,ma,lista,mfit);
- return(0);
- }
-
-